﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using SourceOfMagic.Components;

using RpgLibrary;
using RpgLibrary.CharacterClasses;
using RpgLibrary.SkillClasses;

using XRpgLibrary;
using XRpgLibrary.TileEngine;
using XRpgLibrary.SpriteClasses;
using XRpgLibrary.WorldClasses;
using XRpgLibrary.CharacterClasses;
using XRpgLibrary.InterfaceClasses;
using XRpgLibrary.Controls;

namespace SourceOfMagic.GameScreens
{
    public class GamePlayScreen : BaseGameState
    {
        #region Fields

        static Character player;
        static World world;
        static Engine engine = new Engine(RpgConstants.TileWidth, RpgConstants.TileHeight);
        static Camera camera;

        #endregion

        #region Property Region

        public Camera Camera { get; set; }
      
        public static World World
        {
            get { return world; }
            set 
            {
                world = value;
                world.Camera = camera;
            }
        }

        public static Engine Engine
        {
            get { return engine; }
            set
            {
                engine = value;
            }
        }

        public static Character Player
        {
            get 
            { 
                return player; 
            }
            set 
            {
                if (player != null)
                    player.IsPlayer = false;
                
                if (value != null)
                    value.IsPlayer = true;
                
                player = value;
            }
        }

        private MainMenu mainMenu;
        public MainMenu MainMenu
        {
            get
            {
                if (mainMenu == null)
                    mainMenu = new MainMenu(GameRef);

                return mainMenu;
            }
        }

        #endregion

        #region Constructor Region

        public GamePlayScreen(RpgGame game, GameStateManager manager)
            : base(game, manager)
        {
            camera = new Camera(GameRef.ScreenRectangle);
        }
        
        #endregion

        #region XNA Method Region
        public override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            
            Components.Add(GamePlayScreen.World);

            OverlayComponents.Add(new FpsComponent(GameRef, MenuFont));            
        }

        public override void Update(GameTime gameTime)
        {
            if (!world.IsPaused)
                UpdatePlayerInput(gameTime);

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            DrawWorld(gameTime);
            DrawMenus(gameTime);
        }

        private void DrawMenus(GameTime gameTime)
        {
            GameRef.spriteBatch.Begin(
                SpriteSortMode.Deferred,
                BlendState.NonPremultiplied,
                SamplerState.PointClamp,
                null,
                null,
                null,
                Matrix.Identity);

            base.DrawOverlay(gameTime);

            GameRef.spriteBatch.End();
        }

        private void DrawWorld(GameTime gameTime)
        {
            GameRef.spriteBatch.Begin(
                SpriteSortMode.Deferred,
                BlendState.NonPremultiplied,
                SamplerState.PointClamp,
                null,
                null,
                null,
                camera.Transformation);

            base.Draw(gameTime);

            GameRef.spriteBatch.End();
        }

        private void UpdatePlayerInput(GameTime gameTime)
        {
            camera.Update(gameTime);

            if (InputHandler.KeyReleased(GameCommands.ZoomIn) ||
                InputHandler.ButtonReleased(Buttons.LeftShoulder, PlayerIndex.One))
            {
                camera.ZoomIn();
                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Player.Sprite);
            }
            else if (InputHandler.KeyReleased(GameCommands.ZoomOut) ||
                InputHandler.ButtonReleased(Buttons.RightShoulder, PlayerIndex.One))
            {
                camera.ZoomOut();
                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Player.Sprite);
            }

            Vector2 motion = new Vector2();

            if (InputHandler.KeyDown(GameCommands.MoveUp) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickUp, PlayerIndex.One))
            {
                motion.Y += -1;
            }

            if (InputHandler.KeyDown(GameCommands.MoveDown) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickDown, PlayerIndex.One))
            {
                motion.Y += 1;
            }

            if (InputHandler.KeyDown(GameCommands.MoveLeft) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickLeft, PlayerIndex.One))
            {
                motion.X += -1;
            }

            if (InputHandler.KeyDown(GameCommands.MoveRight) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickRight, PlayerIndex.One))
            {
                motion.X += 1;
            }

            Player.Move(motion, (float)gameTime.ElapsedGameTime.TotalSeconds);
            camera.LockToSprite(Player.Sprite);

            if (InputHandler.KeyReleased(GameCommands.ToggleCameraMode) ||
                InputHandler.ButtonReleased(Buttons.RightStick, PlayerIndex.One))
            {
                camera.ToggleCameraMode();
                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Player.Sprite);
            }

            if (InputHandler.KeyReleased(Keys.OemTilde))
            {
                GameRef.InterfaceManager.PushMenu(MainMenu);
            }

        }


        #endregion
    }
}
